﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Business;
using DBUtility;
using System.Net;
using System.Text;
using System.IO;
using System.Collections;
using System.Drawing;
using Common;
using System.Web.Script.Serialization;
using Newtonsoft.Json.Linq;
using WxPayAPI.lib;
using WxPayAPI;

namespace UI.Controllers
{
    [AllowAnonymousAttribute]
    public class WechatPayController : Controller
    {
        /// <summary>
        /// 调用js获取收货地址时需要传入的参数
        /// 格式：json串
        /// 包含以下字段：
        ///     appid：公众号id
        ///     scope: 填写“jsapi_address”，获得编辑地址权限
        ///     signType:签名方式，目前仅支持SHA1
        ///     addrSign: 签名，由appid、url、timestamp、noncestr、accesstoken参与签名
        ///     timeStamp：时间戳
        ///     nonceStr: 随机字符串
        /// </summary>
        public static string wxEditAddrParam { get; set; }
        // GET: WechatPay
        public ActionResult WechatPay()
        {
            return View();
        }
        string logurl = AppDomain.CurrentDomain.BaseDirectory + "logs\\developLog.txt";
        //支付+重定向
        public ActionResult ProcessPay()
        {
            //string banktype = Request.Form["banktype"];//支付类型 
            //string bankkey = Request.Form["bankkey"];//银行类型
            //string account = Convert.ToString(Request.Form["account"]);//用户账号
            //string merchantno = Request.Form["merchantno"];//商户号
            //decimal amount = Convert.ToDecimal(Request.Form["amount"]);//金额
            //string orderno = Request.Form["orderno"]; //DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(100, 999); //"";//平台订单号
            //string callbackurl = Request.Form["callbackurl"];//回调地址 可能是支付成功后的加钱地址？
            //string sign = Request.Form["sign"];//MD5签名 UTF-8编码 

            string banktype = "4";
            string bankkey = "WEIXINWAP";
            string account = "xiaoke";
            string merchantno = "111";
            decimal amount = Convert.ToDecimal("0.03");
            string orderno = DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(100, 999); //"";//平台订单号//"cccccccsssssssss";

            //StringBuilder sb = new StringBuilder();
            //sb.Append($"；banktype={banktype}");
            //sb.Append($"；bankkey={bankkey}");
            //sb.Append($"；account={account}");
            //sb.Append($"；merchantno={merchantno}");
            //sb.Append($"；amount={amount}");
            //sb.Append($"；orderno={orderno}");
            //sb.Append($"；callbackurl={callbackurl}");
            //sb.Append($"；sign={sign}");
            //LogHelper.Debug(sb.ToString());

            //List<string> list = new List<string>();
            //list.Add("banktype=" + banktype);
            //list.Add("bankkey=" + bankkey);
            //list.Add("account=" + account);
            //list.Add("merchantno=" + merchantno);
            //list.Add("amount=" + amount);
            //list.Add("orderno=" + orderno);
            //list.Sort();
            //string str = "";
            //list.ForEach((string item) => { str += $"{item}&"; });
            //str += "87654321";
            //str = HttpUtility.UrlEncode(str);
            //str = str.Replace("%3d", "%3D");
            //str = StringHelper.DesEncrypt(str);
            int pay_typeID = 0;
            if (banktype == "4")
            {//手机微信
                if (bankkey == "WEIXINWAP")
                {//银行类型：手机微信
                 //然后应该根据商户号来判断用哪个商户号来付款，
                 //用merchantno商户号在数据库查此商户相关配置，如果查不到就随机一个。

                    //PAY_TYPE t_pay_type = new PAY_TYPE().SelectByObj($"mch_id='{merchantno}'");
                    //if (t_pay_type == null)
                    //{
                    //    t_pay_type = new PAY_TYPE().SelectByObj("name='weixin' ORDER BY RAND() LIMIT 1");
                    //}
                    /////////////////////////////
                    PAY_TYPE t_pay_type = new PAY_TYPE().SelectByObj($"title='烟台沃浓商贸'");
                    pay_typeID = t_pay_type.ID;
                    DemoConfig.appid = t_pay_type.app_id;
                    DemoConfig.mchid = t_pay_type.mch_id;
                    DemoConfig.key = t_pay_type.api_key;
                    DemoConfig.appsecret = t_pay_type.app_secret;
                    DemoConfig.sslcertpath = t_pay_type.file;
                    string filepassword = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "/" + t_pay_type.file);
                    DemoConfig.sslcertpassword = filepassword;
                }
            }
            PAY_ORDER t_pay_order = new PAY_ORDER();
            t_pay_order.order_no = orderno;// DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(100, 999);
            t_pay_order.username = account;
            t_pay_order.amount = amount;
            t_pay_order.pay_type = pay_typeID.ToString();//支付渠道，应该要改值
            t_pay_order.state = "N";//是否充值成功
            t_pay_order.addtime = DateTime.Now.ToString();
            t_pay_order.trade_no = "000";//???什么是交易号
            t_pay_order.trade_time = "";//交易时间？？可能是充值成功时间
            t_pay_order.is_check = "N";//是否加钱成功
            t_pay_order.dingdong = "N";//？？？
            t_pay_order.yichang = "N";//异常状态
            t_pay_order.yc_time = "";//异常时间 
            t_pay_order.Insert(ref t_pay_order);
            //按理支付类型、银行类型、商户号、回调地址应该保存下来
            Session["amount"] = amount;
            Session["order_no"] = t_pay_order.order_no;
            //return View();
            return Redirect("/WechatPay/wxPay");
        }

        public ActionResult wxPay()
        {
            string amount = Convert.ToDecimal(Session["amount"]).ToString("f2");

            //初始化微信支付..
            JsApiPay jsApiPay = new JsApiPay();

            try
            {
                //调用【网页授权获取用户信息】接口获取用户的openid和access_token
                jsApiPay.GetOpenidAndAccessToken();

                //获取收货地址js函数入口参数
                wxEditAddrParam = jsApiPay.GetEditAddressParameters();
                ViewBag.openid = jsApiPay.openid;
                ViewBag.wxEditAddrParam = wxEditAddrParam;
                ViewBag.amount = amount;
            }
            catch (Exception ex)
            {
                throw;
            }
            return View();
        }
        public ActionResult wxPay2()
        {
            decimal amount = Convert.ToDecimal(Request.QueryString["amount"]);
            string openid = Request.QueryString["openid"];
            string total_fee = (amount * 100).ToString();//单位 分
            string order_no = Session["order_no"].ToString();
            Session.Remove("order_no");
            Session.Remove("amount");
            //检测是否给当前页面传递了相关参数
            if (string.IsNullOrEmpty(openid) || string.IsNullOrEmpty(total_fee))
            {
                ViewBag.result = "<span style='color:#FF0000;font-size:20px'>" + "页面传参出错,请返回重试" + "</span>";
                return View();
            }
            //若传递了相关参数，则调统一下单接口，获得后续相关接口的入口参数
            JsApiPay jsApiPay = new JsApiPay();
            jsApiPay.openid = openid;
            jsApiPay.total_fee = Convert.ToInt32(Convert.ToDecimal(total_fee));
            jsApiPay.OrderNo = order_no;
            //JSAPI支付预处理
            string wxJsApiParam;
            try
            {
                WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult();
                wxJsApiParam = jsApiPay.GetJsApiParameters();//获取H5调起JS API参数
                //Log.Debug(this.GetType().ToString(), "wxJsApiParam : " + wxJsApiParam);
                System.IO.File.AppendAllText(logurl, string.Format("{0} ：{1} \r\n", DateTime.Now, wxJsApiParam));
                //在页面上显示订单信息
                string str = "<span style='color:#00CD00;font-size:20px'>订单详情：</span><br/>";
                str += "<span style='color:#00CD00;font-size:20px'>" + unifiedOrderResult.ToPrintStr() + "</span>";
                ViewBag.result = str;
                ViewBag.wxJsApiParam = wxJsApiParam;
                return View();
            }
            catch (Exception ex)
            {
                Response.Write("<span style='color:#FF0000;font-size:20px'>" + "下单失败，请返回重试 " + ex.Message.ToString() + "</span>");
                return View();
            }
        }

        /// 支付成功通知回调
        /// 修改订单支付状态，并且加钱。
        public ContentResult ProcessNotify()
        {
            Notify ntf = new Notify();
            WxPayData notifyData = ntf.GetNotifyData();

            if (notifyData.IsSet("transaction_id"))
            {//检查支付结果中transaction_id微信支付订单号存在 才继续
                string transaction_id = notifyData.GetValue("transaction_id").ToString();
                //if (ntf.QueryOrder(transaction_id))
                if (true)
                {//查询微信支付订单号真实有效 再继续- - - - - - - - - - 由于多个商户号查询太麻烦，暂时不查
                    if (notifyData.IsSet("result_code"))
                    {
                        string return_code = notifyData.GetValue("return_code").ToString();//返回通信状态码
                        string result_code = notifyData.GetValue("result_code").ToString();//业务结果
                        int total_fee = Convert.ToInt32(notifyData.GetValue("total_fee"));//金额（分）
                        string out_trade_no = notifyData.GetValue("out_trade_no").ToString();//商户订单号
                        PAY_ORDER t_pay_order = new PAY_ORDER().SelectByObj($"orderNo='{out_trade_no}'");
                        if (t_pay_order.amount * 100 == total_fee && t_pay_order.state == "N" && result_code == "SUCCESS" && return_code == "SUCCESS")
                        {//充值成功 修改订单充值状态
                            //拼接参数往GPO平台用API通知充值成功并且加钱，
                            string callbackurl = "";
                            string account = t_pay_order.username;
                            string orderno = t_pay_order.order_no;//GPO平台传入的订单号
                            string tradestatus = "Success";
                            decimal amount = t_pay_order.amount;//人民币
                            string tradeno = t_pay_order.order_no;//外链订单号 应该就是我们的订单号
                            string actionType = "outreachpay";
                            string sign = "";//md5签名
                            //然后就可以post了
                            t_pay_order.state = "Y";//充值成功
                            t_pay_order.is_check = "Y";//加钱成功。
                            t_pay_order.trade_time = "";//加钱时间
                            t_pay_order.trade_no = "";//交易号?
                            t_pay_order.Update(t_pay_order);
                            List<string> encryptList = new List<string>();
                            string encryptStr = "";
                            encryptList.Add("account=" + account);
                            encryptList.Add("orderno=" + orderno);
                            encryptList.Add("tradestatus=" + tradestatus);
                            encryptList.Add("amount=" + amount);
                            encryptList.Add("tradeno=" + tradeno);
                            encryptList.Sort();
                            encryptList.ForEach((string item) => { encryptStr += $"{item}&"; });
                            encryptStr += "87654321";
                            encryptStr = HttpUtility.UrlEncode(encryptStr);
                            encryptStr = encryptStr.Replace("%3d", "%3D");
                            encryptStr = StringHelper.DesEncrypt(encryptStr);
                            sign = encryptStr.MD5(); 
                        }
                    }
                    else
                    {
                        //下单结果返回为false 可notifyData.ToXml()存日志
                    }
                }
            }
            return Content("");
        }
        #region 登录
        public string requestM(string uName, string passwd, string vaildate)
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create("https://secure.elong.com/passport/ajax/elongLogin");
                request.Method = "Post";
                request.Accept = "application/json, text/javascript, */*; q=0.01";
                request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
                request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36";
                request.AllowAutoRedirect = true;
                //request.CookieContainer = container;//获取验证码时候获取到的cookie会附加在这个容器里面
                request.KeepAlive = true;//建立持久性连接
                //整数据
                string postData = string.Format("userName={0}&passwd={1}&validateCode={2}&rememberMe=true", uName, passwd, vaildate);
                ASCIIEncoding encoding = new ASCIIEncoding();
                byte[] bytepostData = encoding.GetBytes(postData);
                request.ContentLength = bytepostData.Length;

                //发送数据  using结束代码段释放
                using (Stream requestStm = request.GetRequestStream())
                {
                    requestStm.Write(bytepostData, 0, bytepostData.Length);
                }

                //响应
                response = (HttpWebResponse)request.GetResponse();
                string text = string.Empty;
                using (Stream responseStm = response.GetResponseStream())
                {
                    StreamReader redStm = new StreamReader(responseStm, Encoding.UTF8);
                    text = redStm.ReadToEnd();
                }

                return text;
            }
            catch (Exception ex)
            {
                var msg = ex.Message;
                return msg;
            }
        }
        #endregion 

        #region 获取验证码
        public Stream getCodeStream(string codeUrl)
        {

            //验证码请求
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(codeUrl);
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0.1) Gecko/20100101 Firefox/5.0.1";
            request.Accept = "image/webp,*/*;q=0.8";
            request.CookieContainer = new CookieContainer();//!Very Important.!!!
            //container = request.CookieContainer;
            var c = request.CookieContainer.GetCookies(request.RequestUri);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            // response.Cookies = container.GetCookies(request.RequestUri);

            Stream stream = response.GetResponseStream();
            return stream;
        }
        #endregion
    }
}